<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dubbo中ZooKeeper的注册中心角色解析</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
        }
        .hero {
            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
            color: white;
        }
        .card {
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .feature-icon {
            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
        }
        .znode-path {
            font-family: monospace;
            background-color: #f3f4f6;
            padding: 0.25rem 0.5rem;
            border-radius: 0.25rem;
            color: #4f46e5;
        }
        .footer {
            background-color: #1f2937;
        }
        a:hover {
            color: #7c3aed;
        }
        .mermaid {
            background-color: white;
            padding: 1rem;
            border-radius: 0.5rem;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
            margin: 2rem 0;
        }
    </style>
</head>
<body class="antialiased">
    <!-- Hero Section -->
    <section class="hero py-20 px-6 md:py-32">
        <div class="container mx-auto max-w-4xl text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-4">Dubbo中ZooKeeper的注册中心角色解析</h1>
            <p class="text-xl md:text-2xl font-light mb-8 opacity-90">深入理解分布式服务架构中的核心组件协作关系</p>
            <div class="flex justify-center space-x-4">
                <a href="#content" class="px-6 py-3 bg-white text-indigo-600 rounded-full font-medium hover:bg-opacity-90 transition duration-300">
                    <i class="fas fa-book-open mr-2"></i>开始阅读
                </a>
                <a href="#visualization" class="px-6 py-3 border border-white text-white rounded-full font-medium hover:bg-white hover:bg-opacity-10 transition duration-300">
                    <i class="fas fa-project-diagram mr-2"></i>可视化解析
                </a>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-5xl px-6 py-12" id="content">
        <!-- Introduction -->
        <section class="mb-16">
            <p class="text-lg text-gray-700 leading-relaxed mb-6">
                在Dubbo分布式服务框架中，ZooKeeper扮演着至关重要的注册中心角色。它作为服务的"电话簿"，负责存储和管理服务提供者(Producer)和消费者(Consumer)的信息，确保分布式系统中的服务能够高效、可靠地互相发现和调用。
            </p>
            <div class="flex items-center text-indigo-600 font-medium">
                <i class="fas fa-info-circle mr-2"></i>
                <span>ZooKeeper通过其独特的节点结构和监听机制，为Dubbo提供了强大的服务发现与治理能力</span>
            </div>
        </section>

        <!-- Content Sections -->
        <section class="grid md:grid-cols-2 gap-8 mb-16">
            <!-- Service Provider Card -->
            <div class="card bg-white rounded-xl p-8 shadow-lg">
                <div class="flex items-center mb-6">
                    <i class="fas fa-server text-3xl feature-icon mr-4"></i>
                    <h2 class="text-2xl font-bold">1. 服务提供者信息的存储</h2>
                </div>
                <div class="space-y-4">
                    <p><strong>注册服务：</strong>当一个服务提供者启动时，它会将自己提供的服务注册到ZooKeeper中。这包括服务的接口名、版本号、IP地址、端口号等元数据信息。</p>
                    <p>ZooKeeper会为每个服务接口创建一个znode，并在其下创建子节点来存储每个提供者的信息。</p>
                    <div class="bg-gray-50 p-4 rounded-lg">
                        <h4 class="font-semibold mb-2">znode结构：</h4>
                        <ul class="space-y-2">
                            <li><span class="znode-path">/dubbo/com.example.Service/providers/</span> - 服务提供者的目录</li>
                            <li><span class="znode-path">/dubbo/com.example.Service/providers/provider_url</span> - 每个服务提供者对应一个子节点，节点名是服务的URL，内容是服务的元数据</li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- Service Consumer Card -->
            <div class="card bg-white rounded-xl p-8 shadow-lg">
                <div class="flex items-center mb-6">
                    <i class="fas fa-user-clock text-3xl feature-icon mr-4"></i>
                    <h2 class="text-2xl font-bold">2. 服务消费者信息的存储</h2>
                </div>
                <div class="space-y-4">
                    <p><strong>订阅服务：</strong>服务消费者启动时，会向ZooKeeper订阅所需的服务。这意味着消费者会在ZooKeeper中注册自己的信息，以便动态感知服务提供者的变化。</p>
                    <div class="bg-gray-50 p-4 rounded-lg">
                        <h4 class="font-semibold mb-2">znode结构：</h4>
                        <ul class="space-y-2">
                            <li><span class="znode-path">/dubbo/com.example.Service/consumers/</span> - 服务消费者的目录</li>
                            <li><span class="znode-path">/dubbo/com.example.Service/consumers/consumer_url</span> - 每个服务消费者对应一个子节点，节点名是消费者的URL，内容是消费者的元数据</li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>

        <!-- Configuration Section -->
        <section class="mb-16">
            <div class="card bg-white rounded-xl p-8 shadow-lg">
                <div class="flex items-center mb-6">
                    <i class="fas fa-cogs text-3xl feature-icon mr-4"></i>
                    <h2 class="text-2xl font-bold">3. 配置和路由信息的存储</h2>
                </div>
                <p class="mb-4">除了服务提供者和消费者的信息外，Dubbo还会在ZooKeeper中存储一些动态配置和路由信息，如负载均衡策略、权重配置、路由规则等。</p>
                <div class="bg-gray-50 p-4 rounded-lg">
                    <h4 class="font-semibold mb-2">znode结构：</h4>
                    <ul class="space-y-2">
                        <li><span class="znode-path">/dubbo/com.example.Service/configurators/</span> - 配置节点，用于存储服务的动态配置</li>
                        <li><span class="znode-path">/dubbo/com.example.Service/routers/</span> - 路由节点，用于存储服务的路由规则</li>
                    </ul>
                </div>
            </div>
        </section>

        <!-- Node Types Section -->
        <section class="grid md:grid-cols-2 gap-8 mb-16">
            <div class="card bg-white rounded-xl p-8 shadow-lg">
                <div class="flex items-center mb-6">
                    <i class="fas fa-hourglass-half text-3xl feature-icon mr-4"></i>
                    <h2 class="text-2xl font-bold">4. 节点类型</h2>
                </div>
                <div class="space-y-4">
                    <p><strong>临时节点（Ephemeral Nodes）：</strong>服务提供者和消费者的znode通常是临时节点。这意味着当提供者或消费者断开连接时，这些节点会自动删除，确保ZooKeeper中的信息总是最新的。</p>
                    <p><strong>持久节点（Persistent Nodes）：</strong>配置和路由信息通常存储在持久节点中，因为这些信息需要在系统重启后继续保留。</p>
                </div>
            </div>

            <div class="card bg-white rounded-xl p-8 shadow-lg">
                <div class="flex items-center mb-6">
                    <i class="fas fa-sync-alt text-3xl feature-icon mr-4"></i>
                    <h2 class="text-2xl font-bold">5. 工作原理</h2>
                </div>
                <div class="space-y-4">
                    <p><strong>服务注册：</strong>服务提供者启动后，通过Dubbo将服务注册到ZooKeeper中。</p>
                    <p><strong>服务发现：</strong>消费者订阅服务时，通过Dubbo从ZooKeeper获取可用的服务提供者列表，并保持订阅关系以感知服务的动态变化。</p>
                    <p><strong>负载均衡和路由：</strong>当消费者调用服务时，Dubbo会根据配置的负载均衡策略和路由规则，从ZooKeeper中获取最优的服务提供者进行调用。</p>
                </div>
            </div>
        </section>

        <!-- Visualization Section -->
        <section id="visualization" class="mb-16">
            <div class="flex items-center mb-8">
                <i class="fas fa-project-diagram text-3xl feature-icon mr-4"></i>
                <h2 class="text-2xl font-bold">Dubbo与ZooKeeper交互流程图</h2>
            </div>
            <div class="mermaid">
                graph TD
                    A[服务提供者] -->|1. 注册服务| B(ZooKeeper注册中心)
                    C[服务消费者] -->|2. 订阅服务| B
                    B -->|3. 通知变更| C
                    C -->|4. 调用服务| A
            </div>
            
            <div class="mt-8 grid md:grid-cols-2 gap-8">
                <div class="card bg-white rounded-xl p-6 shadow-lg">
                    <h3 class="text-xl font-bold mb-4 text-indigo-600">服务注册流程</h3>
                    <ol class="space-y-3">
                        <li class="flex items-start">
                            <span class="bg-indigo-100 text-indigo-600 rounded-full w-6 h-6 flex items-center justify-center mr-3 flex-shrink-0">1</span>
                            <span>Provider启动并连接ZooKeeper</span>
                        </li>
                        <li class="flex items-start">
                            <span class="bg-indigo-100 text-indigo-600 rounded-full w-6 h-6 flex items-center justify-center mr-3 flex-shrink-0">2</span>
                            <span>创建服务的持久节点</span>
                        </li>
                        <li class="flex items-start">
                            <span class="bg-indigo-100 text-indigo-600 rounded-full w-6 h-6 flex items-center justify-center mr-3 flex-shrink-0">3</span>
                            <span>在providers目录下创建临时节点</span>
                        </li>
                        <li class="flex items-start">
                            <span class="bg-indigo-100 text-indigo-600 rounded-full w-6 h-6 flex items-center justify-center mr-3 flex-shrink-0">4</span>
                            <span>写入服务元数据信息</span>
                        </li>
                    </ol>
                </div>
                
                <div class="card bg-white rounded-xl p-6 shadow-lg">
                    <h3 class="text-xl font-bold mb-4 text-indigo-600">服务发现流程</h3>
                    <ol class="space-y-3">
                        <li class="flex items-start">
                            <span class="bg-indigo-100 text-indigo-600 rounded-full w-6 h-6 flex items-center justify-center mr-3 flex-shrink-0">1</span>
                            <span>Consumer启动并连接ZooKeeper</span>
                        </li>
                        <li class="flex items-start">
                            <span class="bg-indigo-100 text-indigo-600 rounded-full w-6 h-6 flex items-center justify-center mr-3 flex-shrink-0">2</span>
                            <span>查询服务的providers目录</span>
                        </li>
                        <li class="flex items-start">
                            <span class="bg-indigo-100 text-indigo-600 rounded-full w-6 h-6 flex items-center justify-center mr-3 flex-shrink-0">3</span>
                            <span>注册Watcher监听providers变化</span>
                        </li>
                        <li class="flex items-start">
                            <span class="bg-indigo-100 text-indigo-600 rounded-full w-6 h-6 flex items-center justify-center mr-3 flex-shrink-0">4</span>
                            <span>获取当前可用Provider列表</span>
                        </li>
                    </ol>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="footer text-white py-8">
        <div class="container mx-auto px-6">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-4 md:mb-0">
                    <p class="text-lg font-medium">技术小馆</p>
                    <p class="text-gray-300 mt-1">探索技术，分享知识</p>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="hover:text-indigo-300 transition duration-300">
                        <i class="fas fa-globe mr-2"></i>http://www.yuque.com/jtostring
                    </a>
                </div>
            </div>
        </div>
    </footer>

    <!-- Mermaid JS -->
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>